package org.jeecg.modules.tls.rsmg.rsfolder.service.impl;

import com.aliyun.oss.ClientException;
import com.aliyun.oss.OSS;
import com.aliyun.oss.OSSClientBuilder;
import com.aliyun.oss.OSSException;
import com.aliyun.oss.model.*;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import org.jeecg.modules.tls.rsmg.rsfile.entity.RsFile;
import org.jeecg.modules.tls.rsmg.rsfile.mapper.RsFileMapper;
import org.jeecg.modules.tls.rsmg.rsfolder.entity.RsFolder;
import org.jeecg.modules.tls.rsmg.rsfolder.mapper.RsFolderMapper;
import org.jeecg.modules.tls.rsmg.rsfolder.service.IRsFolderService;
import org.jeecg.modules.tls.rsmg.utils.OssUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;

import java.io.ByteArrayInputStream;
import java.io.UnsupportedEncodingException;
import java.net.URLDecoder;
import java.util.ArrayList;
import java.util.List;

/**
 * @Description: rs_folder
 * @Author: jeecg-boot
 * @Date:   2022-07-23
 * @Version: V1.0
 */
@Service
public class RsFolderServiceImpl extends ServiceImpl<RsFolderMapper, RsFolder> implements IRsFolderService {
    @Autowired
    RsFolderMapper rsFolderMapper;
    @Autowired
    RsFileMapper rsFileMapper;

    String endpoint = OssUtil.endpoint;
    String accessKeyId = OssUtil.keyid;
    String accessKeySecret = OssUtil.keysecret;
    String bucketName = OssUtil.bucketName;

    @Override
    public Boolean createFolder(String name, String pid, String userId,String remark) {
        //使用OSS创建目录
        String objectName = "";
        StringBuffer sb = new StringBuffer(objectName);
        //通过pid拿到创建目录所在的路径
        String flagPid = pid;
        while (!flagPid.equals("0")){
            RsFolder rsFolder = rsFolderMapper.selectById(flagPid);
            sb.insert(0,rsFolder.getName()+'/');
            flagPid = rsFolder.getPid();
        }
        objectName = sb.toString() + name + "/localfile.txt";

        String filePath = remark;
        // 创建OSSClient实例。
        OSS ossClient = new OSSClientBuilder().build(endpoint, accessKeyId, accessKeySecret);

        // 创建PutObjectRequest对象。
        try {
            // 创建PutObjectRequest对象。
            PutObjectRequest putObjectRequest = new PutObjectRequest(bucketName, objectName, new ByteArrayInputStream(filePath.getBytes()));
            // 上传字符串。
            ossClient.putObject(putObjectRequest);
        } catch (OSSException oe) {
            System.out.println("Caught an OSSException, which means your request made it to OSS, "
                    + "but was rejected with an error response for some reason.");
            System.out.println("Error Message:" + oe.getErrorMessage());
            System.out.println("Error Code:" + oe.getErrorCode());
            System.out.println("Request ID:" + oe.getRequestId());
            System.out.println("Host ID:" + oe.getHostId());
            return false;
        } catch (ClientException ce) {
            System.out.println("Caught an ClientException, which means the client encountered "
                    + "a serious internal problem while trying to communicate with OSS, "
                    + "such as not being able to access the network.");
            System.out.println("Error Message:" + ce.getMessage());
            return false;
        } finally {
            if (ossClient != null) {
                ossClient.shutdown();
            }
        }
        //如果pid为0则为一级目录
        //否则在数据库中查到路径
        //如果创建成功，则将信息放到实体类中插入到数据库中
        RsFolder rsFolder = new RsFolder();
        rsFolder.setName(name);
        rsFolder.setRemark(remark);
        rsFolder.setPid(pid);
        rsFolder.setUserId(userId);
        rsFolderMapper.insert(rsFolder);
        return true;
    }

    @Override
    public Boolean deleteFolder(String id) {
        //查询该目录所在所在的路径
        RsFolder rsFolder = rsFolderMapper.selectById(id);
        String prefix = "";
        StringBuffer sb = new StringBuffer(prefix);
        String flagPid = rsFolder.getPid();
        while (!flagPid.equals("0")){
            RsFolder pRsFolder = rsFolderMapper.selectById(flagPid);
            sb.insert(0,pRsFolder.getName()+'/');
            flagPid = pRsFolder.getPid();
        }
        // 填写待删除目录的完整路径，完整路径中不包含Bucket名称。
        prefix = sb.toString() + rsFolder.getName() + "/";

        // 创建OSSClient实例。
        OSS ossClient = new OSSClientBuilder().build(endpoint, accessKeyId, accessKeySecret);

        //删除目录
        try {
            // 删除目录及目录下的所有文件。
            String nextMarker = null;
            ObjectListing objectListing = null;
            do {
                ListObjectsRequest listObjectsRequest = new ListObjectsRequest(bucketName)
                        .withPrefix(prefix)
                        .withMarker(nextMarker);

                objectListing = ossClient.listObjects(listObjectsRequest);
                if (objectListing.getObjectSummaries().size() > 0) {
                    List<String> keys = new ArrayList<String>();
                    for (OSSObjectSummary s : objectListing.getObjectSummaries()) {
                        System.out.println("key name: " + s.getKey());
                        keys.add(s.getKey());
                    }
                    DeleteObjectsRequest deleteObjectsRequest = new DeleteObjectsRequest(bucketName).withKeys(keys).withEncodingType("url");
                    DeleteObjectsResult deleteObjectsResult = ossClient.deleteObjects(deleteObjectsRequest);
                    List<String> deletedObjects = deleteObjectsResult.getDeletedObjects();
                    try {
                        for(String obj : deletedObjects) {
                            String deleteObj =  URLDecoder.decode(obj, "UTF-8");
                            System.out.println(deleteObj);
                        }
                    } catch (UnsupportedEncodingException e) {
                        e.printStackTrace();
                    }
                }

                nextMarker = objectListing.getNextMarker();
            } while (objectListing.isTruncated());
        } catch (OSSException oe) {
            System.out.println("Caught an OSSException, which means your request made it to OSS, "
                    + "but was rejected with an error response for some reason.");
            System.out.println("Error Message:" + oe.getErrorMessage());
            System.out.println("Error Code:" + oe.getErrorCode());
            System.out.println("Request ID:" + oe.getRequestId());
            System.out.println("Host ID:" + oe.getHostId());
            return false;
        } catch (ClientException ce) {
            System.out.println("Caught an ClientException, which means the client encountered "
                    + "a serious internal problem while trying to communicate with OSS, "
                    + "such as not being able to access the network.");
            System.out.println("Error Message:" + ce.getMessage());
            return false;
        } finally {
            if (ossClient != null) {
                ossClient.shutdown();
            }
        }
        //删除数据
        delete(id);

        return true;
    }

    @Override
    public String getPathById(String id) {
        StringBuffer sb = new StringBuffer("");
        String flagPid = id;
        while (!flagPid.equals("0")){
            RsFolder pRsFolder = rsFolderMapper.selectById(flagPid);
            sb.insert(0,pRsFolder.getName()+'/');
            flagPid = pRsFolder.getPid();
        }
        return sb.toString();
    }

    //删除目录时，删除对应的子目录和子文件
    private void delete(String id){
        //删除目录对应的所有文件
        QueryWrapper<RsFile> rsFileQueryWrapper = new QueryWrapper<>();
        rsFileQueryWrapper.eq("folder_id",id);
        rsFileMapper.delete(rsFileQueryWrapper);
        //查询有哪些子目录
        QueryWrapper<RsFolder> rsFolderQueryWrapper = new QueryWrapper<>();
        rsFolderQueryWrapper.eq("pid",id);
        List<RsFolder> rsFolderList = rsFolderMapper.selectList(rsFolderQueryWrapper);


        for(RsFolder rsFolder : rsFolderList){
            delete(rsFolder.getId());
        }

        rsFolderMapper.deleteById(id);
    }
}
